winsafe\gui\windows/raw_opts.rs
1use crate::co;
2use crate::decl::*;
3use crate::guard::*;
4use crate::gui::*;
5use crate::prelude::*;
6
7/// Options to create a [`WindowControl`](crate::gui::WindowControl)
8/// programmatically with [`WindowControl::new`](crate::gui::WindowControl::new).
9pub struct WindowControlOpts {
10 /// Window class name to be
11 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
12 ///
13 /// Defaults to an auto-generated string.
14 pub class_name: String,
15 /// Window class styles to be
16 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
17 ///
18 /// Defaults to `co::CS::DBLCLKS`.
19 pub class_style: co::CS,
20 /// Window main icon to be
21 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
22 ///
23 /// Defaults to `gui::Icon::None`.
24 pub class_icon: Icon,
25 /// Window cursor to be
26 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
27 ///
28 /// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
29 pub class_cursor: Cursor,
30 /// Window background brush to be
31 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
32 ///
33 /// Defaults to `gui::Brush::Color(co::COLOR::WINDOW)`.
34 pub class_bg_brush: Brush,
35
36 /// Left and top position coordinates of control within parent's client
37 /// area, to be
38 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
39 ///
40 /// Defaults to `gui::dpi(0, 0)`.
41 pub position: (i32, i32),
42 /// Width and height of window to be
43 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
44 ///
45 /// Defaults to `gui::dpi(100, 80)`.
46 pub size: (i32, i32),
47 /// Window styles to be
48 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
49 ///
50 /// Defaults to `WS::CHILD | WS::TABSTOP | WS::GROUP | WS::VISIBLE | WS::CLIPCHILDREN | WS::CLIPSIBLINGS`.
51 pub style: co::WS,
52 /// Extended window styles to be
53 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
54 ///
55 /// Defaults to `WS_EX::LEFT`.
56 ///
57 /// Suggestion:
58 /// * `WS_EX::CLIENTEDGE` to have a border.
59 pub ex_style: co::WS_EX,
60
61 /// The control ID.
62 ///
63 /// Defaults to an auto-generated ID.
64 pub ctrl_id: u16,
65 /// Horizontal and vertical behavior of the control when the parent window
66 /// is resized.
67 ///
68 /// Defaults to `(gui::Horz::None, gui::Vert::None)`.
69 pub resize_behavior: (Horz, Vert),
70}
71
72impl Default for WindowControlOpts {
73 fn default() -> Self {
74 Self {
75 class_name: "".to_owned(),
76 class_style: co::CS::DBLCLKS,
77 class_icon: Icon::None,
78 class_cursor: Cursor::Idc(co::IDC::ARROW),
79 class_bg_brush: Brush::Color(co::COLOR::WINDOW),
80 position: dpi(0, 0),
81 size: dpi(100, 80),
82 style: co::WS::CHILD
83 | co::WS::TABSTOP
84 | co::WS::GROUP
85 | co::WS::VISIBLE
86 | co::WS::CLIPCHILDREN
87 | co::WS::CLIPSIBLINGS,
88 ex_style: co::WS_EX::LEFT,
89 ctrl_id: 0,
90 resize_behavior: (Horz::None, Vert::None),
91 }
92 }
93}
94
95/// Options to create a [`WindowMain`](crate::gui::WindowMain) programmatically
96/// with [`WindowMain::new`](crate::gui::WindowMain::new).
97pub struct WindowMainOpts {
98 /// Window class name to be
99 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
100 ///
101 /// Defaults to an auto-generated string.
102 pub class_name: String,
103 /// Window class styles to be
104 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
105 ///
106 /// Defaults to `co::CS::DBLCLKS`.
107 pub class_style: co::CS,
108 /// Window main icon to be
109 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
110 ///
111 /// Defaults to `gui::Icon::None`.
112 pub class_icon: Icon,
113 /// Window cursor to be
114 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
115 ///
116 /// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
117 pub class_cursor: Cursor,
118 /// Window background brush to be
119 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
120 ///
121 /// Defaults to `gui::Brush::Color(co::COLOR::BTNFACE)`.
122 pub class_bg_brush: Brush,
123
124 /// Window title to be
125 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
126 ///
127 /// Defaults to empty string.
128 pub title: String,
129 /// Width and height of window client area, in pixels, to be
130 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
131 /// Does not include title bar or borders.
132 ///
133 /// Defaults to `gui::dpi(600, 400)`.
134 pub size: (i32, i32),
135 /// Window styles to be
136 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
137 ///
138 /// Defaults to `WS::CAPTION | WS::SYSMENU | WS::CLIPCHILDREN | WS::BORDER | WS::VISIBLE`.
139 ///
140 /// Suggestions:
141 /// * `WS::SIZEBOX` to make the window resizable;
142 /// * `WS::MINIMIZEBOX` to have a minimize button;
143 /// * `WS::MAXIMIZEBOX` to have a maximize button.
144 pub style: co::WS,
145 /// Extended window styles to be
146 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
147 ///
148 /// Defaults to `WS_EX::LEFT`.
149 pub ex_style: co::WS_EX,
150 /// Main menu of the window to be
151 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
152 ///
153 /// This menu is **not** shared: the window will own it, and destroy it when
154 /// the window is destroyed.
155 ///
156 /// Defaults to none.
157 pub menu: HMENU,
158 /// Main accelerator table of the window to be
159 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
160 /// Use
161 /// [`HACCEL::CreateAcceleratorTable`](crate::HACCEL::CreateAcceleratorTable)
162 /// to create one.
163 ///
164 /// Defaults to `None`.
165 pub accel_table: Option<DestroyAcceleratorTableGuard>,
166 /// In most applications, the window loop calls
167 /// [`IsDialogMessage`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isdialogmessagew)
168 /// so child control messages will properly work. However, this has the side
169 /// effect of inhibiting
170 /// [`WM_CHAR`](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-char)
171 /// messages from being sent to the window procedure. So, applications which
172 /// do not have child controls and deal directly with character processing –
173 /// like text editors – will never be able to receive `WM_CHAR`.
174 ///
175 /// This flag, when `true`, will enable the normal `IsDialogMessage` call in
176 /// the window loop. When `false`, the call will be suppressed.
177 ///
178 /// Defaults to `true`.
179 pub process_dlg_msgs: bool,
180}
181
182impl Default for WindowMainOpts {
183 fn default() -> Self {
184 Self {
185 class_name: "".to_owned(),
186 class_style: co::CS::DBLCLKS,
187 class_icon: Icon::None,
188 class_cursor: Cursor::Idc(co::IDC::ARROW),
189 class_bg_brush: Brush::Color(co::COLOR::BTNFACE),
190 title: "".to_owned(),
191 size: dpi(600, 400),
192 style: co::WS::CAPTION
193 | co::WS::SYSMENU
194 | co::WS::CLIPCHILDREN
195 | co::WS::BORDER
196 | co::WS::VISIBLE,
197 ex_style: co::WS_EX::LEFT,
198 menu: HMENU::NULL,
199 accel_table: None,
200 process_dlg_msgs: true,
201 }
202 }
203}
204
205/// Options to create a [`WindowModal`](crate::gui::WindowModal)
206/// programmatically with [`WindowModal::new`](crate::gui::WindowModal::new).
207pub struct WindowModalOpts {
208 /// Window class name to be
209 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
210 ///
211 /// Defaults to an auto-generated string.
212 pub class_name: String,
213 /// Window class styles to be
214 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
215 ///
216 /// Defaults to `co::CS::DBLCLKS`.
217 pub class_style: co::CS,
218 /// Window main icon to be
219 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
220 ///
221 /// Defaults to `gui::Icon::None`.
222 pub class_icon: Icon,
223 /// Window cursor to be
224 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
225 ///
226 /// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
227 pub class_cursor: Cursor,
228 /// Window background brush to be
229 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
230 ///
231 /// Defaults to `gui::Brush::Color(co::COLOR::BTNFACE)`.
232 pub class_bg_brush: Brush,
233
234 /// Window title to be
235 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
236 ///
237 /// Defaults to empty string.
238 pub title: String,
239 /// Width and height of window client area, in pixels, to be
240 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
241 /// Does not include title bar or borders.
242 ///
243 /// Defaults to `gui::dpi(500, 400)`.
244 pub size: (i32, i32),
245 /// Window styles to be
246 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
247 ///
248 /// Defaults to `WS::CAPTION | WS::SYSMENU | WS::CLIPCHILDREN | WS::BORDER | WS::VISIBLE`.
249 ///
250 /// Suggestions:
251 /// * `WS::SIZEBOX` to make the window resizable;
252 /// * `WS::MAXIMIZEBOX` to have a maximize button.
253 pub style: co::WS,
254 /// Extended window styles to be
255 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
256 ///
257 /// Defaults to `WS_EX::LEFT | WS_EX::DLGMODALFRAME`.
258 pub ex_style: co::WS_EX,
259 /// In most applications, the window loop calls
260 /// [`IsDialogMessage`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isdialogmessagew)
261 /// so child control messages will properly work. However, this has the side
262 /// effect of inhibiting
263 /// [`WM_CHAR`](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-char)
264 /// messages from being sent to the window procedure. So, applications which
265 /// do not have child controls and deal directly with character processing –
266 /// like text editors – will never be able to receive `WM_CHAR`.
267 ///
268 /// This flag, when `true`, will enable the normal `IsDialogMessage` call in
269 /// the window loop. When `false`, the call will be suppressed.
270 ///
271 /// Defaults to `true`.
272 pub process_dlg_msgs: bool,
273}
274
275impl Default for WindowModalOpts {
276 fn default() -> Self {
277 Self {
278 class_name: "".to_owned(),
279 class_style: co::CS::DBLCLKS,
280 class_icon: Icon::None,
281 class_cursor: Cursor::Idc(co::IDC::ARROW),
282 class_bg_brush: Brush::Color(co::COLOR::BTNFACE),
283 title: "".to_owned(),
284 size: dpi(500, 400),
285 style: co::WS::CAPTION
286 | co::WS::SYSMENU
287 | co::WS::CLIPCHILDREN
288 | co::WS::BORDER
289 | co::WS::VISIBLE,
290 ex_style: co::WS_EX::LEFT | co::WS_EX::DLGMODALFRAME,
291 process_dlg_msgs: true,
292 }
293 }
294}
295
296/// Options to create a [`WindowModeless`](crate::gui::WindowModeless)
297/// programmatically with
298/// [`WindowModeless::new`](crate::gui::WindowModeless::new).
299pub struct WindowModelessOpts {
300 /// Window class name to be
301 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
302 ///
303 /// Defaults to an auto-generated string.
304 pub class_name: String,
305 /// Window class styles to be
306 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
307 ///
308 /// Defaults to `co::CS::DBLCLKS`.
309 pub class_style: co::CS,
310 /// Window main icon to be
311 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
312 ///
313 /// Defaults to `gui::Icon::None`.
314 pub class_icon: Icon,
315 /// Window cursor to be
316 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
317 ///
318 /// Defaults to `gui::Cursor::Idc(co::IDC::ARROW)`.
319 pub class_cursor: Cursor,
320 /// Window background brush to be
321 /// [registered](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassexw).
322 ///
323 /// Defaults to `gui::Brush::Color(co::COLOR::BTNFACE)`.
324 pub class_bg_brush: Brush,
325
326 /// Window title to be
327 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
328 ///
329 /// Defaults to empty string.
330 pub title: String,
331 /// Left and top position coordinates of control within parent's client
332 /// area, to be
333 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
334 ///
335 /// Defaults to `gui::dpi(0, 0)`.
336 pub position: (i32, i32),
337 /// Width and height of window client area, in pixels, to be
338 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
339 /// Does not include title bar or borders.
340 ///
341 /// Defaults to `gui::dpi(220, 150)`.
342 pub size: (i32, i32),
343 /// Window styles to be
344 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
345 ///
346 /// Defaults to `WS::CAPTION | WS::SYSMENU | WS::CLIPCHILDREN | WS::BORDER | WS::VISIBLE`.
347 ///
348 /// Suggestions:
349 /// * `WS::SIZEBOX` to make the window resizable.
350 pub style: co::WS,
351 /// Extended window styles to be
352 /// [created](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw).
353 ///
354 /// Defaults to `WS_EX::LEFT | WS_EX::TOOLWINDOW`.
355 pub ex_style: co::WS_EX,
356}
357
358impl Default for WindowModelessOpts {
359 fn default() -> Self {
360 Self {
361 class_name: "".to_owned(),
362 class_style: co::CS::DBLCLKS,
363 class_icon: Icon::None,
364 class_cursor: Cursor::Idc(co::IDC::ARROW),
365 class_bg_brush: Brush::Color(co::COLOR::BTNFACE),
366 title: "".to_owned(),
367 position: dpi(0, 0),
368 size: dpi(220, 150),
369 style: co::WS::CAPTION
370 | co::WS::SYSMENU
371 | co::WS::CLIPCHILDREN
372 | co::WS::BORDER
373 | co::WS::VISIBLE,
374 ex_style: co::WS_EX::LEFT | co::WS_EX::TOOLWINDOW,
375 }
376 }
377}
378
379/// The class background brush to be loaded for
380/// [`WindowMainOpts`](crate::gui::WindowMainOpts),
381/// [`WindowModalOpts`](crate::gui::WindowModalOpts) or
382/// [`WindowControlOpts`](crate::gui::WindowControlOpts).
383pub enum Brush {
384 /// A solid [system color](co::COLOR).
385 Color(co::COLOR),
386 /// A brush handle, previously created by you.
387 Handle(HBRUSH),
388 /// No brush.
389 None,
390}
391
392impl Brush {
393 /// Converts the contents of `Brush` to `HBRUSH`.
394 #[must_use]
395 pub fn as_hbrush(&self) -> HBRUSH {
396 match self {
397 Brush::Color(c) => HBRUSH::from_sys_color(*c),
398 Brush::Handle(h) => unsafe { h.raw_copy() },
399 Brush::None => HBRUSH::NULL,
400 }
401 }
402}
403
404/// The class cursor to be loaded for
405/// [`WindowMainOpts`](crate::gui::WindowMainOpts),
406/// [`WindowModalOpts`](crate::gui::WindowModalOpts) or
407/// [`WindowControlOpts`](crate::gui::WindowControlOpts).
408pub enum Cursor {
409 /// A cursor handle, previously loaded by you.
410 Handle(HCURSOR),
411 /// A resource ID.
412 Id(u16),
413 /// A [`co::IDC`](crate::co::IDC) constant for a stock system cursor.
414 Idc(co::IDC),
415 /// No cursor.
416 None,
417 /// A resource string identifier.
418 Str(WString),
419}
420
421impl Cursor {
422 /// Converts the contents of `Cursor` to `HCURSOR`.
423 #[must_use]
424 pub fn as_hcursor(&self, hinst: &HINSTANCE) -> SysResult<HCURSOR> {
425 unsafe {
426 Ok(match self {
427 Cursor::Handle(h) => h.raw_copy(),
428 Cursor::Id(id) => hinst.LoadCursor(IdIdcStr::Id(*id))?.leak(),
429 Cursor::Idc(idc) => HINSTANCE::NULL.LoadCursor(IdIdcStr::Idc(*idc))?.leak(),
430 Cursor::None => HCURSOR::NULL,
431 Cursor::Str(s) => hinst.LoadCursor(IdIdcStr::Str(s.clone()))?.leak(),
432 })
433 }
434 }
435}
436
437/// The class icon to be loaded for
438/// [`WindowMainOpts`](crate::gui::WindowMainOpts),
439/// [`WindowModalOpts`](crate::gui::WindowModalOpts) or
440/// [`WindowControlOpts`](crate::gui::WindowControlOpts).
441pub enum Icon {
442 /// An icon handle, previously loaded by you.
443 Handle(HICON),
444 /// A resource ID.
445 Id(u16),
446 /// A [`co::IDC`](crate::co::IDC) constant for a stock system icon.
447 Idi(co::IDI),
448 /// No icon.
449 None,
450 /// A resource string identifier.
451 Str(WString),
452}
453
454impl Icon {
455 /// Converts the contents of `Icon` to `HICON`.
456 #[must_use]
457 pub fn as_hicon(&self, hinst: &HINSTANCE) -> SysResult<HICON> {
458 unsafe {
459 Ok(match self {
460 Icon::Handle(h) => h.raw_copy(),
461 Icon::Id(id) => hinst.LoadIcon(IdIdiStr::Id(*id))?.leak(),
462 Icon::Idi(idi) => HINSTANCE::NULL.LoadIcon(IdIdiStr::Idi(*idi))?.leak(),
463 Icon::None => HICON::NULL,
464 Icon::Str(s) => hinst.LoadIcon(IdIdiStr::Str(s.clone()))?.leak(),
465 })
466 }
467 }
468}